import os

import pandas as pd
from docx import Document
from docxcompose.composer import Composer
from docxtpl import DocxTemplate


class ExcelToWord:
    def __init__(self):
        self.project_root = os.path.dirname(os.path.abspath(__file__))  # 项目根目录

        # 默认路径
        self.excel_path = os.path.join(self.project_root, 'excel', '测试用例.xlsx')  # excel路径
        self.template_path = os.path.join(self.project_root, 'template', 'template.docx')  # 模板路径
        self.output_path = os.path.join(self.project_root, 'output')  # 输出路径

    def set_paths(self, excel_path=None, template_path=None, output_path=None):
        """
        手动设置路径
        :param excel_path: excel路径
        :param template_path: 模板路径
        :param output_path: 输出路径
        :return:
        """
        if excel_path:
            self.excel_path = excel_path
        if template_path:
            self.template_path = template_path
        if output_path:
            self.output_path = output_path

    def gen_word(self):
        """
        生成 word 文档
        :return:
        """
        os.makedirs(self.output_path, exist_ok=True)

        try:
            df = pd.read_excel(self.excel_path)
        except Exception as e:
            raise RuntimeError(f"读取Excel失败: {e}")

        for index, row in df.iterrows():
            try:
                doc = DocxTemplate(self.template_path)
                context = row.to_dict()
                doc.render(context)

                output_filename = f"{index + 1}.docx"
                output_file = os.path.join(self.output_path, output_filename)
                doc.save(output_file)
            except Exception as e:
                print(f"处理第 {index + 1} 行时出错: {e}")
                continue

        print(f"单个文档生成完成，保存在: {self.output_path}")

    def merge_word(self):
        """
        合并 word 文档
        :return:
        """
        # 先删除output目录下的merged.docx
        merged_file = os.path.join(self.output_path, 'merged.docx')
        if os.path.exists(merged_file):
            os.remove(merged_file)

        word_files = [f for f in os.listdir(self.output_path) if f.endswith('.docx')]
        word_files.sort(key=lambda x: int(x.split('.')[0]))  # 按编号排序

        if not word_files:
            print("没有找到要合并的文档")
            return

        master = Document(os.path.join(self.output_path, word_files[0]))
        composer = Composer(master)

        for file in word_files[1:]:
            doc = Document(os.path.join(self.output_path, file))
            composer.append(doc)

        merged_file = os.path.join(self.output_path, 'merged.docx')
        composer.save(merged_file)

        for file in word_files:
            file_path = os.path.join(self.output_path, file)
            if file_path != merged_file:
                try:
                    os.remove(file_path)
                except Exception as e:
                    print(f"删除文件 {file_path} 失败: {e}")

        print(f"文档已合并到: {merged_file}")

    def run(self):
        """
        生成 + 合并
        :return:
        """
        self.gen_word()
        self.merge_word()


if __name__ == "__main__":
    converter = ExcelToWord()
    converter.run()
